package codeflyer.server;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import org.apache.log4j.Logger;

import codeFlyer.web.api.Filter;
import codeFlyer.web.api.HttpServlet;
import codeFlyer.web.api.Listener;
import codeflyer.server.classload.ClassLoad;
import codeflyer.server.utils.AnalysisXml;
import codeflyer.server.utils.PropertiesAnalysis;

/**
 * @author CodeFlyer
 * @date Apr 21, 2020
 * @version 1.0
 */

public class Main {
	
	static {
		String logPath = new File("").getAbsolutePath().replaceAll("\\\\", "/");
		StringBuilder sb = new StringBuilder(logPath);  
		sb.append("/log");
		logPath = sb.toString();
		System.setProperty("log.base", logPath);
	}
	
	private static Logger logger = Logger.getLogger(Main.class);
	
	private static ExecutorService executorService = Executors.newCachedThreadPool();

	public static void main(String[] args) {
		
		boolean exist = ClassLoad.myClassLoad(); //在项目启动前加载所有项目的所有类
		System.setProperty("java.net.preferIPv4Stack", "true");     //设置一下使用Ipv4地址
		System.out.println(exist);
		logger.info(exist);    //判断webapp目录下有没有项目
		if(exist = true) {		
			List<String> proFileList = ClassLoad.getJarFolderList();  //包括斜杆
			for (String project : proFileList) {  //每有一个项目新建一个线程
				//这里就把当前线程的类加载器替换成每个项目的URLClassLoader
				Thread.currentThread().setContextClassLoader(ClassLoad.getProClassLoader().get(project));
				project = project.substring(0, project.lastIndexOf("/"));  //去除最后一个斜杆
				//按理说这里要给每一个项目都开启一个新的线程
				//端口号由项目所携带的web.properties文件来指定			
				Map fpMap = PropertiesAnalysis.getPMap();    //得到项目和端口号的键值对
				String port = (String) fpMap.get(project);
				System.out.println("端口号和项目名称-------->"+port+"--"+project);	
				
				Map<String, List<HttpServlet>> servletMap = new ConcurrentHashMap<>();  //存储项目的所有servlet对象和路径
				Map<String, List<Filter>> filterMap = new ConcurrentHashMap<>();       //存储项目的所有filter对象
				List<Listener> listenerList = new CopyOnWriteArrayList<>();    //存储项目的所有listener对象
				
				//--------------------------------web.api对象的生成----------------------------------
				List<String> lPath = AnalysisXml.getListenerList();
				if(lPath.size()>0) {
					for (String path : lPath) {
						try {
							System.out.println("Listener的路径"+lPath);
							Class clazz = ClassLoad.getProClassLoader().get(project).loadClass(path);  //得到某个项目的类加载器
							Listener listener = (Listener) clazz.newInstance();
							if(listener!=null) {
								listenerList.add(listener);
							}
							System.out.println("监听器遍历次数"+"1");
						} catch (ClassNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (InstantiationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}		
				//------------------------------加载所有的Listener结束--------------------------------	
				System.out.println("URLClassLoader的父类加载器---------------------------->"+ClassLoad.getProClassLoader().get(project).getParent());;
				ApplicationContext applicationContext = new ApplicationContext(listenerList);
//				if(applicationContext.getFilterMap().size()<=0 || applicationContext.getServletMap().size()<=0) {
					//获取某个项目下所有的filter和servlet
					Map<String, List<Map<String, List<String>>>> hsmap = AnalysisXml.getHsmapping();  //得到路径和servlet类名				
					if(hsmap.size()>0) {
						List<Map<String, List<String>>> xmlList = hsmap.get(project);
						for (Map<String, List<String>> map : xmlList) {
							//根据路径匹配对应的servlet进行加载
							for(Entry<String, List<String>> entry:map.entrySet()) {
								String httpPath = entry.getKey();
								List<String> classList = entry.getValue();
								for (String servletPath : classList) {  //list的里的个数随着每次遍历而增加
									//通过类加载反射来创建对象,调用doget方法
									try {
										Class clazz = ClassLoad.getProClassLoader().get(project).loadClass(servletPath);  //得到某个项目的类加载器
										HttpServlet servlet = (HttpServlet) clazz.newInstance();
										if(servletMap.get(httpPath)!=null) {
											servletMap.get(httpPath).add(servlet);
										}else {
											List<HttpServlet> slList = new ArrayList<>();
											slList.add(servlet);
											servletMap.put(httpPath, slList);
										}
										System.out.println("servlet遍历次数"+"1");
									} catch (ClassNotFoundException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (InstantiationException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								}				
							}
						}
					}
					
					//------------------------------加载所有的servlet结束--------------------------------					
					Map<String, List<Map<String, List<String>>>> hfmap = AnalysisXml.getHfmapping();  //得到路径和servlet类名
					
					if(hfmap.size()>0) {
						List<Map<String, List<String>>> xmlLList = hfmap.get(project);
						for (Map<String, List<String>> map : xmlLList) {
							//根据路径匹配对应的servlet进行加载
							for(Entry<String, List<String>> entry:map.entrySet()) {
								String httpPath = entry.getKey();
								List<String> classList = entry.getValue();
								for (String filterPath : classList) {  //list的里的个数随着每次遍历而增加
									//通过类加载反射来创建对象,调用doget方法
									try {
										Class clazz = ClassLoad.getProClassLoader().get(project).loadClass(filterPath);
										Filter filter = (Filter) clazz.newInstance();
										if(filterMap.get(httpPath)!=null) {
											filterMap.get(httpPath).add(filter);
										}else {
											List<Filter> llList = new ArrayList<>();
											llList.add(filter);
											filterMap.put(httpPath, llList);
										}
										System.out.println("过滤器遍历次数"+"1");
									} catch (ClassNotFoundException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (InstantiationException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								}				
							}
						}
					}
					//------------------------------加载所有的filter结束--------------------------------	
//				}
				
			
				ServerStart serverStart = new ServerStart(port, project);				
				serverStart.setApplicationContext(applicationContext);
				serverStart.setFilterMap(filterMap);
				serverStart.setListenerList(listenerList);
				serverStart.setServletMap(servletMap);
				executorService.execute(serverStart);
			}
			
		}else {
			
		}				
		
	}
	
}


